using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Abp.Application.Services;
using Abp.Application.Services.Dto;
using Abp.Linq.Extensions;
using Abp.Domain.Repositories;
using Microsoft.EntityFrameworkCore;
using Sunlit.House.Buy.Dto;
using Abp.Extensions;
using Sunlit.House.Authorization;
using Abp.Runtime.Session;
using Sunlit.House.Users;
using Sunlit.House.Authorization.Users;

namespace Sunlit.House.Buy
{
    public class GroupBuyAppService: AsyncCrudAppService<GroupBuy,GroupBuyDto,long,GetAllGroupBuyInput,
        CreateGroupBuyInput,UpdateGroupBuyInput>,IGroupBuyAppService
    {
        private readonly IRepository<GroupBuyType, long> _groupBuyTypeRepository;
        private readonly IRepository<GroupItem, long> _groupItemRepository;
        private readonly IRepository<User, long> _userRepository;

        public GroupBuyAppService(IRepository<GroupBuy,long> repository,
            IRepository<GroupBuyType, long> groupBuyTypeRepository,
            IRepository<User, long> userRepository,
            IRepository<GroupItem, long> groupItemRepository) :base(repository)
        {
            CreatePermissionName = PermissionNames.Pages_GroupBuy_OpenGroup;
            UpdatePermissionName = PermissionNames.Pages_GroupBuy_OpenGroup;
            DeletePermissionName = PermissionNames.Pages_GroupBuy_OpenGroup;

            _groupBuyTypeRepository = groupBuyTypeRepository;
            _userRepository = userRepository;
            _groupItemRepository = groupItemRepository;
        }
        protected override IQueryable<GroupBuy> CreateFilteredQuery(GetAllGroupBuyInput input)
        {
            return base.CreateFilteredQuery(input)
                .Include(b=>b.GroupBuyType)
                .WhereIf(input.IsActive.HasValue, b => b.IsActive == input.IsActive)
                .WhereIf(!input.PhoneNumber.IsNullOrWhiteSpace(), b => b.PhoneNumber == input.PhoneNumber)
                .WhereIf(!input.LinkMan.IsNullOrWhiteSpace(), b => b.LinkMan.Contains(input.LinkMan));
        }
        public async Task<PagedResultDto<GroupBuyDto>> GetAllAndChildAsync(GetAllGroupBuyInput input)
        {
            var result = await base.GetAllAsync(input);
            foreach (var item in result.Items)
            {
                var child = await _groupItemRepository.GetAllListAsync(i => i.GroupBuyId == item.Id);
                item.children = ObjectMapper.Map<List<GroupItemDto>>(child);
            }
            return result;
        }
        public override async Task<GroupBuyDto> CreateAsync(CreateGroupBuyInput input)
        {
            var buyType = await _groupBuyTypeRepository.GetAsync(input.GroupBuyTypeId);
            input.NeedCount = buyType.NeedCount;
            input.State = GroupState.OnGoing;
            input.CurrentCount = 1;
            input.EndDate = DateTime.Now.AddDays(buyType.DayLimit);
            input.ChiefProfit = buyType.ChiefProfit;
            input.IsActive = input.CreatorUserId.HasValue;

            if (!input.PhoneNumber.IsNullOrEmpty())
            {
                var user = await _userRepository.GetAsync(AbpSession.GetUserId());
                user.PhoneNumber = input.PhoneNumber;
            }

            return await base.CreateAsync(input);
        }
        public override async Task<GroupBuyDto> UpdateAsync(UpdateGroupBuyInput input)
        {
            var buyType = await _groupBuyTypeRepository.GetAsync(input.GroupBuyTypeId);
            input.NeedCount = buyType.NeedCount;
            input.EndDate = DateTime.Now.AddDays(buyType.DayLimit);
            input.ChiefProfit = buyType.ChiefProfit;

            return await base.UpdateAsync(input);
        }
        public async Task EnActive(EntityDto<long> input)
        {
            var entity = await Repository.GetAsync(input.Id);
            entity.IsActive = true;
        }
        public async Task DeActive(EntityDto<long> input)
        {
            var entity = await Repository.GetAsync(input.Id);
            entity.IsActive = false;
        }
        public async Task<List<GroupBuyDto>> GetAllMyList()
        {
            var userId = AbpSession.GetUserId();
            var list = await Repository.GetAll()
                .Include(g => g.GroupBuyType)
                .Where(g => g.CreatorUserId == userId)
                .ToListAsync();

            return ObjectMapper.Map<List<GroupBuyDto>>(list);
        }
        public async Task<List<GroupBuyDto>> GetAllListByFloorId(EntityDto<long> input)
        {
            var list = await Repository.GetAll()
                .Include(g => g.GroupBuyType)
                .Where(g => g.IsActive && g.FloorId == input.Id && g.State == GroupState.OnGoing)
                .ToListAsync();

            return ObjectMapper.Map<List<GroupBuyDto>>(list);
        }
        public override async Task<GroupBuyDto> GetAsync(EntityDto<long> input)
        {
            var entity = await base.GetAsync(input);
            entity.GroupBuyTypeName = (await _groupBuyTypeRepository.GetAsync(entity.GroupBuyTypeId)).Name;
            return entity;
        }
    }
}
